// #region demo
// #region common
package crud

// 导入依赖包
// #region import
import (
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

// #endregion import

// 定义数据表对应的结构体
type User struct {
	ID   uint
	Name string
	Age  uint8
}

// #endregion common

// #region create
func Create() {
	// 创建结构体实例变量
	user := User{Name: "shann", Age: 20}

	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	if err == nil {
		// 数据表
		db.AutoMigrate(&user)

		// 新增记录
		result := db.Create(&user)

		if result.Error == nil {
			println(user.ID) // => 1
		}
	}
}

// #endregion create

// #region batch-create
func BatchCreate() {
	users := []User{
		{Name: "Jinzhu", Age: 18},
		{Name: "Jackson", Age: 19},
	}

	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	if err == nil {
		// 新增记录
		result := db.Create(users)

		if result.Error == nil {
			println(result.RowsAffected) // => 2
		}
	}
}

// #endregion batch-create

// #region create-with-fields
func CreateWithFields() {
	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	// 准备新增的记录
	user := User{Name: "Shann", Age: 18}

	if err == nil {
		// 新增记录
		result := db.Select("Name").Create(&user)

		if result.Error == nil {
			println(user.Name) // => Shann
		}
	}
}

// #endregion create-with-fields

// #region create-without-fields
func CreateWithOutFields() {
	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	// 准备新增的记录
	user := User{Name: "Shann", Age: 18}

	if err == nil {
		// 新增记录
		result := db.Omit("Name").Create(&user)

		if result.Error == nil {
			println(user.Name)
		}
	}
}

// #endregion create-without-fields

// #region before-create
func UseBeforeCreate() {
	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	// 准备新增的记录
	user := User{Name: "Shann"}

	// 无错误
	if err == nil {
		// 新增记录
		db.Create(&user)

		// 新增记录（忽略钩子）
		// db.Session(&gorm.Session{SkipHooks: true}).Create(&user)
	}
}

// 钩子函数
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
	// 自动填充
	if u.Age <= 0 {
		u.Age = 18
	}
	return
}

// #endregion before-create

// #region use-map-create
func UseMapCreate() {
	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	// 无错误
	if err == nil {
		// 映射
		db.Model(&User{}).Create(map[string]interface{}{
			"Name": "Shann",
			"Age":  26,
		})

		// 映射集合
		db.Model(&User{}).Create([]map[string]interface{}{
			{"Name": "Shann", "Age": 26},
			{"Name": "Linda", "Age": 18},
		})
	}
}

// #endregion use-map-create

// #region use-sql
func UseSqlCreate() {
	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	// 无错误
	if err == nil {
		// 新增
		// db.Model(User{}).Create(map[string]interface{}{
		// 	"Name": "Shann",
		// 	"Age":  clause.Expr{SQL: "CONVERT(?, SIGNED)", Vars: []interface{}{"30"}},
		// })

		// SQL
		user := db.Debug().Model(User{}).Create(map[string]interface{}{
			"Name": "Shann",
			"Age":  clause.Expr{SQL: "CONVERT(?, SIGNED)", Vars: []interface{}{"30"}},
		})
		fmt.Println(user)
	}
}

// #endregion use-sql

// #region associations
func CreateWithAssociations() {
	type CreditCard struct {
		ID     uint `gorm:"primarykey"`
		Number string
		UserID uint
	}

	type User struct {
		ID         uint `gorm:"primarykey"`
		Name       string
		CreditCard CreditCard
	}

	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	// 无错误
	if err == nil {
		creditCard := CreditCard{Number: "411111111111"}

		db.AutoMigrate(&creditCard)

		db.Create(&User{
			Name:       "jinzhu",
			CreditCard: creditCard,
		})
	}
}

// #endregion associations

// #region default-values
func CreateWithDefaultValues() {
	type User struct {
		ID   uint   `gorm:"primarykey"`
		Name string `gorm:"default:shann"`
		Age  string `gorm:"default:20"`
	}

	// 创建数据库连接实例
	db, err := CreateDB()

	// 无错误
	if err == nil {
		db.Create(&User{})
	}
}

// #endregion default-values

// #region db
func CreateDB() (db *gorm.DB, err error) {
	// 数据库配置
	dsn := "root:root@tcp(127.0.0.1:3306)/test-gorm"

	// 创建数据库连接实例
	return gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

// #endregion db

// #endregion demo
